﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DiscoveryLogic.DataViz.NetworkDiagram.Measures
{
    /// <summary>
    /// 
    /// </summary>
    public class GraphMeasureWorker
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="edges"></param>
        /// <returns></returns>
        public static Dictionary<Guid,int> GetVerticeDegrees(Dictionary<Guid, Vertice> vertices, Dictionary<Guid, Edge> edges)
        {
            Dictionary<Guid,int> vDegrees=new Dictionary<Guid, int>();
            foreach (Edge e in edges.Values)
            {
                if (vDegrees.ContainsKey(e.VerticeID1))
                    vDegrees[e.VerticeID1] = vDegrees[e.VerticeID1] + 1;
                else
                    vDegrees.Add(e.VerticeID1, 1);
                if (vDegrees.ContainsKey(e.VerticeID2))
                    vDegrees[e.VerticeID2] = vDegrees[e.VerticeID2] + 1;
                else
                    vDegrees.Add(e.VerticeID2, 1);
            }
            return vDegrees;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="edges"></param>
        /// <returns></returns>
        public static Dictionary<Guid,double> CalculateVerticeBetweennessCentrality(Dictionary<Guid,Vertice> vertices, Dictionary<Guid,Edge> edges)
        {
            Dictionary<Guid,double> vMeasures=new Dictionary<Guid, double>();
            BetweennessCentralityMeasure centralityMeasure=new BetweennessCentralityMeasure();
            Graph g = new Graph();
            g.Vertices = vertices;
            g.Edges = edges;
            foreach(Vertice v in vertices.Values)
            {
                double val = centralityMeasure.GetVerticeMeasure(g, v);
                vMeasures.Add(v.ID,val);
            }
            return vMeasures;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="edges"></param>
        /// <returns></returns>
        public static Dictionary<Guid, double> CalculateVerticeCloseCentrality(Dictionary<Guid, Vertice> vertices, Dictionary<Guid, Edge> edges)
        {
            Dictionary<Guid, double> vMeasures = new Dictionary<Guid, double>();
            ClosenessCentrality closenessCentrality=new ClosenessCentrality();
            Graph g = new Graph();
            g.Vertices = vertices;
            g.Edges = edges;
            
            foreach (Vertice v in vertices.Values)
            {
                double val = closenessCentrality.GetVerticeMeasure(g, v);
                vMeasures.Add(v.ID, val);
            }
            return vMeasures;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="edges"></param>
        /// <returns></returns>
        public static Dictionary<Guid, int> GetVerticeOutDegrees(Dictionary<Guid, Vertice> vertices, Dictionary<Guid, Edge> edges)
        {
            Dictionary<Guid, int> vOutDegrees = new Dictionary<Guid, int>();
            foreach (Edge e in edges.Values)
            {
                if(e is Arc)
                {
                    if (vOutDegrees.ContainsKey(e.VerticeID1))
                        vOutDegrees[e.VerticeID1] = vOutDegrees[e.VerticeID1] + 1;
                    else
                        vOutDegrees.Add(e.VerticeID1, 1);
                }
            }
            return vOutDegrees;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="edges"></param>
        /// <returns></returns>
        public static Dictionary<Guid, int> GetVerticeInDegrees(Dictionary<Guid, Vertice> vertices, Dictionary<Guid, Edge> edges)
        {
            Dictionary<Guid, int> vInDegrees = new Dictionary<Guid, int>();
            foreach (Edge e in edges.Values)
            {
                if(e is Arc)
                {
                    if (vInDegrees.ContainsKey(e.VerticeID2))
                        vInDegrees[e.VerticeID2] = vInDegrees[e.VerticeID2] + 1;
                    else
                        vInDegrees.Add(e.VerticeID2, 1);
                }
            }
            return vInDegrees;
        }
    }
}
